package ecmnext.business.operations;

/***************************************************************/
/*                     SOFTWARE SECTION                        */
/***************************************************************/
/*
 * <p>Name: ECMNext</p>
 * <p>Description: Simulation of the platform of trading Software</p>
 * <p>Licence: General Public License</p>
 * <p>Organisation: EC Marseille</p>
 * <p>Persons involved in the project : groupe Plateforme de Trading</p>
 * <p>Current version: 1.0</p>
 */


/***************************************************************/
/*                       IMPORT SECTION                        */
/***************************************************************/

import org.jdom.*;
import ecmnext.business.*;
import javax.swing.*;
import ecmnext.utils.*;

/***************************************************************/
/*                 LimitOrder CLASS SECTION                    */
/***************************************************************/
/**
 * <p>Title : LimitOrder</p>
 * <p>Description : </p>

 * @author Xuewen YANG ET Antoine COUDERC
 * @version 1.0
 */

public class LimitOrder extends Order {

  private static final String operationName = "Limit Order";

  private Integer quantity;
  private Float price;

  public int getQuantity() {
    return this.quantity.intValue();
  }

  public float getPrice() {
    return this.price.floatValue();
  }

  public void setPrice(float price) {
    this.price = new Float(price);
  }

  public void setQuantity(int qtty) {
    this.quantity = new Integer(qtty);
  }

  public float getOperationCost(float percentCost, float minimalCost) {
    return Math.max(minimalCost,
                    quantity.intValue() * price.floatValue() *
                    percentCost / 100 );
  }


  public LimitOrder() {
    super();
  }

  public String getOperationName() {
    return operationName;
  }

  public boolean initFromNetworkInput(Element node) {
    if (!super.initFromNetworkInput(node)) {
      return false;
    }

    Element limitOrder = node.getChild("LimitOrder");
    String price = limitOrder.getAttributeValue("price");
    String quantity = limitOrder.getAttributeValue("quantity");
    if ((price == null) || (quantity == null)) {
      Utils.logger.error("Invalid xml limitorder node: the attribute price or quantity is missing.");
      return false;
    }

    this.price = new Float(price);
    this.quantity = new Integer(quantity);

    return true;
  }

  public Element prepareForNetworkOutput(String pt) {
    Element root = super.prepareForNetworkOutput(pt);

    Element limitOrder = new Element("LimitOrder");
    limitOrder.setAttribute("price",this.price.toString());
    limitOrder.setAttribute("quantity",this.quantity.toString());

    root.addContent(limitOrder);
    return root;
  }

  public boolean isExecutingImmediately() {
    return false;
  }

  public void stopImmediateExecution() {
    //Must never happen !
  }

  public boolean hasDefinedPrice() {
    return true;
  }

  public boolean isVisibleInOrderbook() {
    return true;
  }

  public void definePrice(float price) {
    //must never happen !
  }

  public boolean isVisibleInTheClientPanel() {
    return true;
  }

  public ClientInputPanel getClientPanel(String institution) {
    return new LimitOrderClientPanel(institution);
  }

  public int getMinQtty() {
    return 1;
  }

  public int getMaxQtty() {
    return this.getQuantity();
  }

  /**
   * The min price at which the order could be executed
   * @return float
   */
  public float getMinPrice() {
    return (this.getSide() == Order.BID) ? 0 : this.getPrice();
  }

  /**
   * The max price at which this order could be executed
   * @return float
   */
  public float getMaxPrice() {
    return (this.getSide() == Order.BID) ?  this.getPrice() : Float.MAX_VALUE;
  }

  public void setRemainingOrder(int quantity, float price) {
    this.quantity = new Integer(this.quantity.intValue() - quantity);
  }

  static {
    try {
      System.out.println("Loading LimitOrder...");
      ecmnext.business.OperationCreator.operationFactories.put(operationName , Class.forName("ecmnext.business.operations.LimitOrder"));
    }
    catch (ClassNotFoundException exception) {
      // it's highly doubtful we won't find jessx.business.operations.LimitOrder
      System.out.println("Unabled to locate the LimitOrder class. Reason: bad class name spelling.");
      exception.printStackTrace();
    }
  }
}
